package com.srmt.document.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 权限设置
 * 
 * @author YourCompany
 * @since 1.0.0
 */
public class PermissionSetting implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 权限类型
     */
    private PermissionType type;
    
    /**
     * 只读用户列表
     */
    private List<String> readUsers;
    
    /**
     * 可写用户列表
     */
    private List<String> writeUsers;
    
    /**
     * 管理员用户列表
     */
    private List<String> adminUsers;
    
    /**
     * 评论用户列表
     */
    private List<String> commentUsers;
    
    /**
     * 是否公开文档
     */
    private boolean isPublic;
    
    /**
     * 公开链接的权限级别
     */
    private String publicPermissionLevel;
    
    /**
     * 是否允许评论
     */
    private boolean allowComment;
    
    /**
     * 是否允许复制
     */
    private boolean allowCopy;
    
    /**
     * 是否允许下载
     */
    private boolean allowDownload;
    
    /**
     * 是否允许打印
     */
    private boolean allowPrint;
    
    /**
     * 是否需要通知
     */
    private boolean needNotification;
    
    // 构造函数
    public PermissionSetting() {
        this.readUsers = new ArrayList<>();
        this.writeUsers = new ArrayList<>();
        this.adminUsers = new ArrayList<>();
        this.commentUsers = new ArrayList<>();
        this.isPublic = false;
        this.allowComment = true;
        this.allowCopy = true;
        this.allowDownload = true;
        this.allowPrint = true;
        this.needNotification = false;
    }
    
    // Builder构造函数
    private PermissionSetting(Builder builder) {
        this.type = builder.type;
        this.readUsers = builder.readUsers != null ? new ArrayList<>(builder.readUsers) : new ArrayList<>();
        this.writeUsers = builder.writeUsers != null ? new ArrayList<>(builder.writeUsers) : new ArrayList<>();
        this.adminUsers = builder.adminUsers != null ? new ArrayList<>(builder.adminUsers) : new ArrayList<>();
        this.commentUsers = builder.commentUsers != null ? new ArrayList<>(builder.commentUsers) : new ArrayList<>();
        this.isPublic = builder.isPublic;
        this.publicPermissionLevel = builder.publicPermissionLevel;
        this.allowComment = builder.allowComment;
        this.allowCopy = builder.allowCopy;
        this.allowDownload = builder.allowDownload;
        this.allowPrint = builder.allowPrint;
        this.needNotification = builder.needNotification;
    }
    
    // 便利方法
    
    /**
     * 添加只读用户
     */
    public void addReadUser(String userId) {
        if (!readUsers.contains(userId)) {
            readUsers.add(userId);
        }
    }
    
    /**
     * 添加可写用户
     */
    public void addWriteUser(String userId) {
        if (!writeUsers.contains(userId)) {
            writeUsers.add(userId);
        }
    }
    
    /**
     * 添加管理员用户
     */
    public void addAdminUser(String userId) {
        if (!adminUsers.contains(userId)) {
            adminUsers.add(userId);
        }
    }
    
    /**
     * 添加评论用户
     */
    public void addCommentUser(String userId) {
        if (!commentUsers.contains(userId)) {
            commentUsers.add(userId);
        }
    }
    
    /**
     * 移除用户的所有权限
     */
    public void removeUser(String userId) {
        readUsers.remove(userId);
        writeUsers.remove(userId);
        adminUsers.remove(userId);
        commentUsers.remove(userId);
    }
    
    // Getters and Setters
    public PermissionType getType() {
        return type;
    }
    
    public void setType(PermissionType type) {
        this.type = type;
    }
    
    public List<String> getReadUsers() {
        return readUsers;
    }
    
    public void setReadUsers(List<String> readUsers) {
        this.readUsers = readUsers;
    }
    
    public List<String> getWriteUsers() {
        return writeUsers;
    }
    
    public void setWriteUsers(List<String> writeUsers) {
        this.writeUsers = writeUsers;
    }
    
    public List<String> getAdminUsers() {
        return adminUsers;
    }
    
    public void setAdminUsers(List<String> adminUsers) {
        this.adminUsers = adminUsers;
    }
    
    public List<String> getCommentUsers() {
        return commentUsers;
    }
    
    public void setCommentUsers(List<String> commentUsers) {
        this.commentUsers = commentUsers;
    }
    
    public boolean isPublic() {
        return isPublic;
    }
    
    public void setPublic(boolean isPublic) {
        this.isPublic = isPublic;
    }
    
    public String getPublicPermissionLevel() {
        return publicPermissionLevel;
    }
    
    public void setPublicPermissionLevel(String publicPermissionLevel) {
        this.publicPermissionLevel = publicPermissionLevel;
    }
    
    public boolean isAllowComment() {
        return allowComment;
    }
    
    public void setAllowComment(boolean allowComment) {
        this.allowComment = allowComment;
    }
    
    public boolean isAllowCopy() {
        return allowCopy;
    }
    
    public void setAllowCopy(boolean allowCopy) {
        this.allowCopy = allowCopy;
    }
    
    public boolean isAllowDownload() {
        return allowDownload;
    }
    
    public void setAllowDownload(boolean allowDownload) {
        this.allowDownload = allowDownload;
    }
    
    public boolean isAllowPrint() {
        return allowPrint;
    }
    
    public void setAllowPrint(boolean allowPrint) {
        this.allowPrint = allowPrint;
    }
    
    public boolean isNeedNotification() {
        return needNotification;
    }
    
    public void setNeedNotification(boolean needNotification) {
        this.needNotification = needNotification;
    }
    
    // Builder Pattern
    public static Builder builder() {
        return new Builder();
    }
    
    public static class Builder {
        private PermissionType type;
        private List<String> readUsers;
        private List<String> writeUsers;
        private List<String> adminUsers;
        private List<String> commentUsers;
        private boolean isPublic = false;
        private String publicPermissionLevel;
        private boolean allowComment = true;
        private boolean allowCopy = true;
        private boolean allowDownload = true;
        private boolean allowPrint = true;
        private boolean needNotification = false;
        
        public Builder type(PermissionType type) {
            this.type = type;
            return this;
        }
        
        public Builder readUsers(List<String> readUsers) {
            this.readUsers = readUsers;
            return this;
        }
        
        public Builder writeUsers(List<String> writeUsers) {
            this.writeUsers = writeUsers;
            return this;
        }
        
        public Builder adminUsers(List<String> adminUsers) {
            this.adminUsers = adminUsers;
            return this;
        }
        
        public Builder commentUsers(List<String> commentUsers) {
            this.commentUsers = commentUsers;
            return this;
        }
        
        public Builder isPublic(boolean isPublic) {
            this.isPublic = isPublic;
            return this;
        }
        
        public Builder publicPermissionLevel(String publicPermissionLevel) {
            this.publicPermissionLevel = publicPermissionLevel;
            return this;
        }
        
        public Builder allowComment(boolean allowComment) {
            this.allowComment = allowComment;
            return this;
        }
        
        public Builder allowCopy(boolean allowCopy) {
            this.allowCopy = allowCopy;
            return this;
        }
        
        public Builder allowDownload(boolean allowDownload) {
            this.allowDownload = allowDownload;
            return this;
        }
        
        public Builder allowPrint(boolean allowPrint) {
            this.allowPrint = allowPrint;
            return this;
        }
        
        public Builder needNotification(boolean needNotification) {
            this.needNotification = needNotification;
            return this;
        }
        
        // 便利方法 - 添加单个用户权限
        public Builder addReadUser(String userId) {
            if (this.readUsers == null) {
                this.readUsers = new ArrayList<>();
            }
            if (!this.readUsers.contains(userId)) {
                this.readUsers.add(userId);
            }
            return this;
        }
        
        public Builder addWriteUser(String userId) {
            if (this.writeUsers == null) {
                this.writeUsers = new ArrayList<>();
            }
            if (!this.writeUsers.contains(userId)) {
                this.writeUsers.add(userId);
            }
            return this;
        }
        
        public Builder addAdminUser(String userId) {
            if (this.adminUsers == null) {
                this.adminUsers = new ArrayList<>();
            }
            if (!this.adminUsers.contains(userId)) {
                this.adminUsers.add(userId);
            }
            return this;
        }
        
        public Builder addCommentUser(String userId) {
            if (this.commentUsers == null) {
                this.commentUsers = new ArrayList<>();
            }
            if (!this.commentUsers.contains(userId)) {
                this.commentUsers.add(userId);
            }
            return this;
        }
        
        // 便利方法 - 批量添加用户
        public Builder addReadUsers(String... userIds) {
            for (String userId : userIds) {
                addReadUser(userId);
            }
            return this;
        }
        
        public Builder addWriteUsers(String... userIds) {
            for (String userId : userIds) {
                addWriteUser(userId);
            }
            return this;
        }
        
        public Builder addAdminUsers(String... userIds) {
            for (String userId : userIds) {
                addAdminUser(userId);
            }
            return this;
        }
        
        public Builder addCommentUsers(String... userIds) {
            for (String userId : userIds) {
                addCommentUser(userId);
            }
            return this;
        }
        
        // 便利方法 - 设置公开权限
        public Builder makePublic(String permissionLevel) {
            this.isPublic = true;
            this.publicPermissionLevel = permissionLevel;
            return this;
        }
        
        public Builder makePrivate() {
            this.isPublic = false;
            this.publicPermissionLevel = null;
            return this;
        }
        
        // 便利方法 - 设置文档功能权限
        public Builder allowAll() {
            this.allowComment = true;
            this.allowCopy = true;
            this.allowDownload = true;
            this.allowPrint = true;
            return this;
        }
        
        public Builder restrictAll() {
            this.allowComment = false;
            this.allowCopy = false;
            this.allowDownload = false;
            this.allowPrint = false;
            return this;
        }
        
        public PermissionSetting build() {
            return new PermissionSetting(this);
        }
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        PermissionSetting that = (PermissionSetting) o;
        return isPublic == that.isPublic &&
                allowComment == that.allowComment &&
                allowCopy == that.allowCopy &&
                allowDownload == that.allowDownload &&
                allowPrint == that.allowPrint &&
                needNotification == that.needNotification &&
                type == that.type &&
                Objects.equals(readUsers, that.readUsers) &&
                Objects.equals(writeUsers, that.writeUsers) &&
                Objects.equals(adminUsers, that.adminUsers) &&
                Objects.equals(commentUsers, that.commentUsers) &&
                Objects.equals(publicPermissionLevel, that.publicPermissionLevel);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(type, readUsers, writeUsers, adminUsers, commentUsers, 
                          isPublic, publicPermissionLevel, allowComment, allowCopy, 
                          allowDownload, allowPrint, needNotification);
    }
    
    // 实用方法
    
    /**
     * 获取用户在当前权限设置中的最高权限
     */
    public PermissionType getUserPermission(String userId) {
        if (adminUsers != null && adminUsers.contains(userId)) {
            return PermissionType.ADMIN;
        }
        if (writeUsers != null && writeUsers.contains(userId)) {
            return PermissionType.READ_WRITE;
        }
        if (commentUsers != null && commentUsers.contains(userId)) {
            return PermissionType.COMMENT;
        }
        if (readUsers != null && readUsers.contains(userId)) {
            return PermissionType.READ_ONLY;
        }
        return null; // 用户没有权限
    }
    
    /**
     * 检查是否有任何用户权限设置
     */
    public boolean hasAnyUserPermissions() {
        return (readUsers != null && !readUsers.isEmpty()) ||
               (writeUsers != null && !writeUsers.isEmpty()) ||
               (adminUsers != null && !adminUsers.isEmpty()) ||
               (commentUsers != null && !commentUsers.isEmpty());
    }
    
    /**
     * 获取所有有权限的用户ID列表
     */
    public List<String> getAllUserIds() {
        List<String> allUsers = new ArrayList<>();
        if (readUsers != null) allUsers.addAll(readUsers);
        if (writeUsers != null) allUsers.addAll(writeUsers);
        if (adminUsers != null) allUsers.addAll(adminUsers);
        if (commentUsers != null) allUsers.addAll(commentUsers);
        
        // 去重
        return allUsers.stream().distinct().collect(Collectors.toList());
    }
    
    /**
     * 统计有权限的用户总数
     */
    public int getTotalUserCount() {
        return getAllUserIds().size();
    }
    
    /**
     * 创建权限设置的副本
     */
    public PermissionSetting copy() {
        PermissionSetting copy = new PermissionSetting();
        copy.type = this.type;
        copy.readUsers = this.readUsers != null ? new ArrayList<>(this.readUsers) : new ArrayList<>();
        copy.writeUsers = this.writeUsers != null ? new ArrayList<>(this.writeUsers) : new ArrayList<>();
        copy.adminUsers = this.adminUsers != null ? new ArrayList<>(this.adminUsers) : new ArrayList<>();
        copy.commentUsers = this.commentUsers != null ? new ArrayList<>(this.commentUsers) : new ArrayList<>();
        copy.isPublic = this.isPublic;
        copy.publicPermissionLevel = this.publicPermissionLevel;
        copy.allowComment = this.allowComment;
        copy.allowCopy = this.allowCopy;
        copy.allowDownload = this.allowDownload;
        copy.allowPrint = this.allowPrint;
        copy.needNotification = this.needNotification;
        return copy;
    }
    
    @Override
    public String toString() {
        return "PermissionSetting{" +
                "type=" + type +
                ", readUsers=" + (readUsers != null ? readUsers.size() : 0) + " users" +
                ", writeUsers=" + (writeUsers != null ? writeUsers.size() : 0) + " users" +
                ", adminUsers=" + (adminUsers != null ? adminUsers.size() : 0) + " users" +
                ", commentUsers=" + (commentUsers != null ? commentUsers.size() : 0) + " users" +
                ", isPublic=" + isPublic +
                ", allowComment=" + allowComment +
                ", allowCopy=" + allowCopy +
                ", needNotification=" + needNotification +
                '}';
    }
}